﻿using DevExpress.Images;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
using Inaction.Mapping;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace Inaction.UI.Extensions.ControlExtensions.Grid
{
    public class GridRowBatchSetHelper
    {
        #region 属性或变量
        BindingSource bindingSource;

        BarManager barManager;

        GridControl gridControl;
        GridView gridView;

        Color batchSetColor = Color.Yellow;

        bool canBatchSet;
        public bool CanBatchSet
        {
            get { return canBatchSet && barManager.EditMode; }
            set { canBatchSet = value; }
        }

        List<BaseEdit> editList = new List<BaseEdit>();

        bool multiSelect = false;

        GridMultiSelectMode selectMode = GridMultiSelectMode.RowSelect;

        bool inited = false;

        bool inEdit = false;
        #endregion

        #region 构造
        public GridRowBatchSetHelper(GridControl gridControl, BarManager barManager)
        {
            gridView = gridControl.MainView as GridView;
            if (gridView == null || barManager == null) return;
            this.gridControl = gridControl;
            this.barManager = barManager;
            bindingSource = gridControl.DataSource as BindingSource;
            multiSelect = gridView.OptionsSelection.MultiSelect;
            selectMode = gridView.OptionsSelection.MultiSelectMode;
            gridView.PopupMenuShowing += gridView_PopupMenuShowing;
        }
        #endregion

        #region  方法
        public static void Extend(GridControl gridControl)
        {
            if (gridControl.DataSource != null && gridControl.DataSource is BindingSource)
            {
                var barManager = BarManager.GetBarManager(gridControl.FindForm());
                if (barManager == null) return;
                new GridRowBatchSetHelper(gridControl, barManager);
            }
        }
        #endregion

        #region 事件

        private void SetPropertyValue(object business, string propertyName, object value)
        {
            var model = business as Inaction.Core.ModelBase;
            var classInfo = ClassInfo.LoadInfo(business.GetType());
            classInfo.NameProperties[propertyName].SetFieldValue(model, value);
        }

        #region 初始化
        void gridView_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e)
        {
            if (e.HitInfo.Column == null) return;
            var item = e.Menu.Items.Cast<DevExpress.Utils.Menu.DXMenuItem>().FirstOrDefault(p => p.Caption == "批量修改");
            if (item == null)
            {
                item = new DevExpress.Utils.Menu.DXMenuItem("批量修改");
                item.Tag = e.HitInfo.Column;
                item.Image = Properties.Resources.BatchEdit;
                e.Menu.Items.Insert(0, item);
                item.Click += batchSet_Click;
            }

            item.Visible = bindingSource.List.Count != 0 && e.HitInfo.InColumn && barManager.EditMode;
            if (!inited)
            {
                if (barManager.BindingInfos.Any(p => p.BindingSource == bindingSource && p.AllowEdit == true))
                {
                    foreach (Binding binding in bindingSource.CurrencyManager.Bindings)
                    {
                        var baseEdit = binding.Control as BaseEdit;
                        if (baseEdit == null) continue;
                        editList.Add(baseEdit);
                        baseEdit.KeyDown += baseEdit_KeyDown;
                        baseEdit.TextChanged += baseEdit_TextChanged;
                    }
                    barManager.OperateStateChanged += barManager_OperateStateChanged;
                    barManager.Saving += barManager_Saving;
                    barManager.Canceling += barManager_Canceling;
                }
                inited = true;
            }
        }
        void barManager_OperateStateChanged(object sender, EventArgs e)
        {
            if (!barManager.EditMode)
            {
                ResumeEditProperty();
            }
        }

        void barManager_Canceling(object sender, BarItemClickEventArgs e)
        {
            ResumeEditProperty();
        }

        void barManager_Saving(object sender, BarItemClickEventArgs e)
        {
            ResumeEditProperty();
        }

        void baseEdit_KeyDown(object sender, KeyEventArgs e)
        {
            if (inEdit || !CanBatchSet) return;
            inEdit = CanBatchSet;
            gridControl.Enabled = false;
        }

        void baseEdit_TextChanged(object sender, EventArgs e)
        {
            if (!inEdit || !CanBatchSet) return;
            var selectedIndexs = gridView.GetSelectedRows();
            if (selectedIndexs.Length == 0) return;
            var baseEdit = sender as BaseEdit;
            foreach (var index in selectedIndexs)
            {
                var entity = gridView.GetRow(index) as object;
                if (entity == bindingSource.Current) continue;
                SetPropertyValue(entity, baseEdit.DataBindings[0].BindingMemberInfo.BindingField, baseEdit.EditValue);
            }
        }
        #endregion

        void batchSet_Click(object sender, EventArgs e)
        {
            if (CanBatchSet == true)
            {
                ResumeEditProperty();
                return;
            }
            CanBatchSet = true;
            foreach (var baseEdit in editList)
            {
                baseEdit.Properties.Appearance.BackColor = batchSetColor;
            }
            gridView.OptionsSelection.MultiSelectMode = GridMultiSelectMode.RowSelect;
            gridView.OptionsSelection.MultiSelect = true;
            gridView.Appearance.SelectedRow.BackColor = batchSetColor;
        }
        void ResumeEditProperty()
        {
            CanBatchSet = false;
            inEdit = false;
            foreach (var baseEdit in editList)
            {
                baseEdit.Properties.Appearance.BorderColor = Color.Empty;
            }
            gridView.OptionsSelection.MultiSelect = multiSelect;
            gridView.OptionsSelection.MultiSelectMode = selectMode;
            gridView.Appearance.SelectedRow.BackColor = Color.Empty;
            gridControl.Enabled = true;
        }
        #endregion
    }
}